﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.UI.Data;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.UI.Views
{
    /// <summary>
    /// Interaction logic for RenderView.xaml
    /// 用于显示的主视图
    /// </summary>
    public partial class RenderView : View
    {
        public Metadata.Solution Solution { get; private set; }
        public Metadata.Scene CurrentScene { get; private set; }
        public Metadata.Area CurrentArea { get; private set; }

        /// <summary>
        /// 弹出视图
        /// </summary>
        private List<UI.Views.PopView> _popViews;

        /// <summary>
        /// 是否在加载时创建新的组件实例，当弹出一个新的场景时，我们需要创建一个新的场景对象防止一个场景加载到多个renderview中
        /// 到后期应该考虑，一个renderview打包一组场景实例
        /// </summary>
        private bool _isLoadPartFromCache = true;

        public PartFrame PartFrame
        {
            get
            {
                return _ctlMainFrame;
            }
        }

        public RenderView()
        {
            InitializeComponent();

            _ctlMainFrame.OnSceneUpdated += _ctlMainFrame_OnSceneUpdated;
            _ctlMainFrame.OnSceneOpened += _ctlMainFrame_OnSceneOpened;

            // 初始化viewstate
            _viewState = Coolzon.ViewState.ViewState.FromToken(string.Empty);
        }

        public RenderView(Metadata.Solution solution)
            : this()
        {
            Solution = solution;

            _ctlMainFrame.IsCanScroll = true;
            _ctlMainFrame.DisplayMode = PartFrameDisplayMode.Original;//.HStretch;
            _popViews = new List<PopView>();

            _ctlMainFrame.Init(Solution);

            if (Solution != null && _viewState != null)
            {
                _viewState.SolutionName = Solution.Name;
            }
        }

        /// <summary>
        /// 子renderview中显示的组件，每次都重新创建
        /// </summary>
        /// <param name="parentView"></param>
        public RenderView(RenderView parentView)
            : this(parentView.Solution)
        {
            _isLoadPartFromCache = true;

            _ctlMainFrame.SetAutoSize();
        }

        /// <summary>
        /// 设置显示模式
        /// </summary>
        /// <param name="mode"></param>
        public void SetDisplayMode(PartFrameDisplayMode mode)
        {
            _ctlMainFrame.DisplayMode = mode;
        }

        protected override void OnActive()
        {
            if (IsFirstActive)
            {
            }
        }

        protected override void OnClose()
        {
            _ctlMainFrame.Clear();
        }

        /// <summary>
        /// 切换到场景
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="args"></param>
        public bool SwitchToScene(string sceneName, OpenSceneArgs args)
        {
            if (CurrentScene != null && CurrentScene.Name == sceneName)
            {
                if (args != null && args.GetBool("sys:isresetviewstate"))
                {
                    // 还原到初始状态
                    (_ctlMainFrame.CurrentPart as ScenePart).Reset();
                    // 发送更新事件
                    Common.EventBus.Instance.Publish(new SceneUpdateEvent(_ctlMainFrame.CurrentPart as ScenePart, SceneUpdateReason.ResetScene));
                }
                return true;
            }

            Metadata.Scene bingoSceneMetadata = Metadata.SolutionUtil.GetScene(Solution, sceneName);

            if (bingoSceneMetadata != null)
            {
                if (_ctlMainFrame.PartContext != null)
                {
                    _ctlMainFrame.PartContext.IsShowActiveXPart = UIContext.Current.IsShowActiveXPart;
                }

                CurrentScene = bingoSceneMetadata;
                UI.Part scene = null;
                if (CurrentScene.IsShowInNavigation)
                {
                    if (Solution.PartCacheMode == Metadata.PartCacheMode.NoCache)
                    {
                        scene = PartInstanceCache.GetSceneInstance("scene", bingoSceneMetadata, false);
                        scene.Init(_ctlMainFrame.PartContext);
                    }
                    else
                    {
                        scene = PartInstanceCache.GetSceneInstance("scene", bingoSceneMetadata, true);
                        if (scene != null
                            && args != null
                            && args.GetBool("sys:isresetviewstate"))
                        {
                            (scene as UI.ScenePart).Reset();

                            // 发送更新事件
                            Common.EventBus.Instance.Publish(new SceneUpdateEvent(_ctlMainFrame.CurrentPart as ScenePart, SceneUpdateReason.ResetScene));
                        }
                    }
                }
                else
                {
                    if (Solution.PartCacheMode == Metadata.PartCacheMode.NoCache)
                    {
                        scene = PartInstanceCache.GetSceneInstance("scene", bingoSceneMetadata, false);
                        scene.Init(_ctlMainFrame.PartContext);
                    }
                    else
                    {
                        scene = PartInstanceCache.GetSceneInstance("scene", bingoSceneMetadata, true);
                    }
                }
                if (args != null)
                {
                    foreach (string key in args.ParametersString.Keys)
                    {
                        Debug.WriteLine(string.Format("注入属性Name:{0}\tValue:{1}到场景:{2}", key, args.ParametersString[key], scene.Name));
                        scene.Parameters.Set(key, args.ParametersString[key]);
                    }
                }

                if (scene != null)
                {
                    _ctlMainFrame.ShowPart(scene, SwitchAnimationFactory.Create("FADE"));
                }

                _ctlMainFrame.Active(bingoSceneMetadata, UIContext.Current.IsShowActiveXPart, args);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 切换显示一个区域
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="areaName"></param>
        public void SwitchToArea(string sceneName, string areaName)
        {
            if (CurrentArea != null && CurrentArea.Name == areaName)
            {
                return;
            }

            Metadata.Scene bingoSceneMetadata = Metadata.SolutionUtil.GetScene(Solution, sceneName);
            Metadata.Area bingoAreaMetadata = Metadata.SolutionUtil.GetArea(Solution, sceneName, areaName);
            if (bingoAreaMetadata != null)
            {
                CurrentScene = bingoSceneMetadata;
                CurrentArea = bingoAreaMetadata;
                UI.Part areaPart = PartInstanceCache.GetAreaInstance(bingoSceneMetadata, bingoAreaMetadata);

                if (areaPart != null)
                {
                    _ctlMainFrame.ShowPart(areaPart, SwitchAnimationFactory.Create("FADE"));
                }
                _ctlMainFrame.Active(null);
            }
        }

        /// <summary>
        /// 滚动到区域
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="area"></param>
        public void ScrollToArea(Metadata.Scene sceneMetadata, Metadata.Area areaMetadata)
        {
            if (CurrentScene == null || CurrentScene.Name != sceneMetadata.Name)
            {
                return;
            }

            if (sceneMetadata != null)
            {
                CurrentScene = sceneMetadata;
                UI.ScenePart scenePart = PartInstanceCache.GetSceneInstance("scene", sceneMetadata, _isLoadPartFromCache) as UI.ScenePart;

                if (scenePart != null)
                {
                    UI.AreaPart areaPart = scenePart.GetChildPart(areaMetadata.Name, false) as AreaPart;
                    if (areaPart != null)
                    {
                        scenePart.ResetHorizontalLoop();
                        _ctlMainFrame.ScrollToPart(areaPart);
                    }
                }
                //_ctlMainFrame.Active();
            }
        }

        /// <summary>
        /// 滚动到一个具体的位置
        /// </summary>
        /// <param name="offsetX"></param>
        /// <param name="offsetY"></param>
        public void ScrollToPos(double offsetX, double offsetY)
        {
            _ctlMainFrame.MoveCameraToPos(offsetX, offsetY);
        }

        private void _ctlCheckOriginal_Checked(object sender, RoutedEventArgs e)
        {
            if (sender == _ctlCheckOriginal)
            {
                _ctlMainFrame.DisplayMode = PartFrameDisplayMode.Original;
            }
            else if (sender == _ctlCheckHStretch)
            {
                _ctlMainFrame.DisplayMode = PartFrameDisplayMode.HStretch;
            }
            else if (sender == _ctlCheckVStretch)
            {
                _ctlMainFrame.DisplayMode = PartFrameDisplayMode.VStretch;
            }
            else
            {
                _ctlMainFrame.DisplayMode = PartFrameDisplayMode.Stretch;
            }
            _ctlMainFrame.UpdateDisplayMode();

            if (_ctlMainFrame.FrameSize != null && _ctlMainFrame.ContentSize != null)
            {
                _ctlTextSize.Text = string.Format("{0}-{1}/{2}-{3}", _ctlMainFrame.FrameSize.Width,
                    _ctlMainFrame.FrameSize.Height,
                    _ctlMainFrame.ContentSize.Width,
                    _ctlMainFrame.ContentSize.Height);
            }
        }

        #region open/pop scene

        /// <summary>
        /// 切换场景
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="frameName"></param>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <param name="data"></param>
        public void OpenScene(SwitchMode mode, string frameName, string type, string name, OpenSceneArgs args)
        {
            Coolzon.Common.Logger.DebugToTag("Coolon.UI", "打开场景:\"{0}\",mode:\"{1}\"",
                name,
                mode);

            if (mode == SwitchMode.Replace)
            {
                OnOpenScene(frameName, type, name, args);
            }
            else
            {
                OnPopScene(frameName, type, name, args);
            }
        }

        /// <summary>
        /// 打开场景
        /// </summary>
        /// <param name="frameName"></param>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <param name="args"></param>
        private void OnOpenScene(string frameName, string type, string name, OpenSceneArgs args)
        {
            this.Dispatcher.Invoke(() =>
            {
                #region 关闭弹出层
                for (int index = 0; index < _popViews.Count; index++)
                {
                    _popViews[index].Submit();
                    PopView popView = _popViews[index] as PopView;
                    ScenePart scene = (popView.ContentView as RenderView).GetCurrentPart() as ScenePart;
                    if (scene != null)
                    {
                        Common.Logger.DebugToTag("UI", "销毁-位置2,PopView，Name:{0}", scene.XFullName);
                        scene.Destory();
                    }
                    else
                    {
                        Common.Logger.ErrorToTag("UI", "存在弹出层，弹出层里没有场景，弹出视图里的contentView：{0}", popView.ContentView);
                    }
                    Common.Logger.DebugToTag("UI", "ClearAllParts -OnBack, sceneName:{0}", popView.GetSceneName());
                    (popView.ContentView as RenderView).ClearAllParts();
                }
                _popViews.Clear();
                #endregion

                try
                {

                    if (SwitchToScene(name, args))
                    {
                        // 更新viewState
                        this._viewState.OpenScene(name, OpenSceneArgs.GetParametersString(args));
                        this._viewState.Update();

                        Coolzon.Event.Core.CoreOpenSceneCompletedEvent @event = new Coolzon.Event.Core.CoreOpenSceneCompletedEvent(SwitchMode.Replace, frameName, name, args);
                        Coolzon.Event.Core.CoreEventBus.Publish(@event);
                    }
                }
                catch(Exception ex)
                {

                    Common.Logger.ErrorToTag("Coolzon.UI", "RenderView.OnOpenScene发生错误,scene：{0}, ex:{1}", name, ex);
                    
                }
            });
        }

        private void OnPopScene(string frameName, string type, string name, OpenSceneArgs args)
        {
            this.Dispatcher.Invoke(() =>
            {
                Metadata.Scene scene = Metadata.SolutionUtil.GetScene(Solution, name);
                if (scene != null)
                {
                    //检查是否在弹出的场景里已经有这个场景了
                    for (int index = 0; index < this._popViews.Count; index++)
                    {
                        if (string.Equals((this._popViews[index].ContentView as RenderView).CurrentScene.Name, scene.Name))
                        {
                            Logger.DebugToTag(Library.LogTag, string.Format("pop scene:{0}失败，因为场景已经在弹出列表中", scene.Name));
                            return;
                        }
                    }

                    CPPEI.Coolzon.UI.Views.RenderView contentView = new CPPEI.Coolzon.UI.Views.RenderView(this);
                    //contentView.Width = scene.;
                    //contentView.Height = 400;
                    contentView.Tag = scene;
                    PopView popView = new PopView(contentView);
                    this._ctlLayout.Children.Add(popView);
                    contentView.GetPartContext().IsRoot = false;
                    contentView.SwitchToScene(name, args);

                    if (contentView.GetCurrentPart() != null)
                    {
                    }

                    if (_ctlMainFrame.CurrentPart != null)
                    {
                        // 冻结当前的场景
                        _ctlMainFrame.CurrentPart.Frozen();
                    }

                    popView.Close += popView_Close;
                    _popViews.Add(popView);

                    // 更新viewState
                    this._viewState.PopScene(name, OpenSceneArgs.GetParametersString(args));
                    this._viewState.Update();

                    Coolzon.Event.Core.CoreOpenSceneCompletedEvent @event = new Coolzon.Event.Core.CoreOpenSceneCompletedEvent(SwitchMode.Pop, frameName, name, args);
                    Coolzon.Event.Core.CoreEventBus.Publish(@event);
                }
                else
                {
                    Common.Logger.ErrorToTag("UI", "RenderView pop view失败，未发现场景:{0}", name);
                }
            });
        }

        #endregion

        /// <summary>
        /// 退出场景
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="frameName"></param>
        /// <param name="type"></param>
        /// <param name="name"></param>
        public void OnBack(SwitchMode mode, string frameName, string type, string name)
        {
            this.Dispatcher.Invoke(() =>
            {
                if (mode == SwitchMode.Pop)
                {
                    for (int index = 0; index < _popViews.Count; index++)
                    {
                        PopView view = _popViews[index];
                        if (view.GetSceneName() == name)
                        {
                            ScenePart scene = (view.ContentView as RenderView).GetCurrentPart() as ScenePart;
                            if (scene != null)
                            {
                                Common.Logger.DebugToTag("UI", "销毁-位置1,PopView，Name:{0}", scene.XFullName);
                                scene.Destory();
                            }
                            else
                            {
                                Common.Logger.ErrorToTag("UI", "存在弹出层，弹出层里没有场景，弹出视图里的contentView：{0}", view.ContentView);
                            }
                            Common.Logger.DebugToTag("UI", "ClearAllParts -OnBack, sceneName:{0}", name);
                            (view.ContentView as RenderView).ClearAllParts();
                            this._ctlLayout.Children.Remove(view);
                            this._popViews.RemoveAt(index);

                            // 更新视图状态
                            this._viewState.CloseScene(name);
                            this._viewState.Update();

                            // 发送场景关闭事件
                            Coolzon.Event.Core.CoreCloseSceneCompletedEvent @closeEvent = new Coolzon.Event.Core.CoreCloseSceneCompletedEvent(SwitchMode.Pop,
                                frameName,
                                name);
                            Coolzon.Event.Core.CoreEventBus.PublishAsync(@closeEvent);
                            break;
                        }
                    }

                    if (_popViews.Count == 0)
                    {
                        if (_ctlMainFrame.CurrentPart != null)
                        {
                            // 冻结当前的场景
                            _ctlMainFrame.CurrentPart.Unfreeze();

                            // 发送场景打开事件
                            Coolzon.Event.Core.CoreOpenSceneCompletedEvent @event = new Coolzon.Event.Core.CoreOpenSceneCompletedEvent(SwitchMode.Replace, "", _ctlMainFrame.CurrentPart.Name, null);
                            Coolzon.Event.Core.CoreEventBus.Publish(@event);
                        }
                    }
                }
                else
                {
                    if (_ctlMainFrame.CurrentPart != null)
                        Common.Logger.DebugToTag("UI", "OnBack-Replace,Name:{0}", _ctlMainFrame.CurrentPart.Name);
                    else
                    {
                        Common.Logger.DebugToTag("UI", "OnBack-Replace");
                    }
                    _ctlMainFrame.Back();

                    Coolzon.Event.Core.CoreCloseSceneCompletedEvent @closeEvent = new Coolzon.Event.Core.CoreCloseSceneCompletedEvent(SwitchMode.Replace,
                        frameName,
                        name);
                    Coolzon.Event.Core.CoreEventBus.PublishAsync(@closeEvent);
                    // bug
                    CurrentScene = null;
                }
            });
        }

        void popView_Close(View view, bool isCancel)
        {
            this._ctlLayout.Children.Remove(view);
        }

        public void OnScrollToArea(string frameName, Metadata.Solution solution, Metadata.Scene scene, Metadata.Area area)
        {
            ScrollToArea(scene, area);
        }

        /// <summary>
        /// 获取当前显示的组件
        /// </summary>
        /// <returns></returns>
        public UI.Part GetCurrentPart()
        {
            if(_ctlMainFrame.CurrentPart == null)
            {
                Logger.ErrorToTag("RenderView", "CurrentPart为空");
            }
            return _ctlMainFrame.CurrentPart;
        }

        /// <summary>
        /// 预加载part
        /// </summary>
        /// <param name="scenePart"></param>
        public void PreliminaryLoadPart(UI.ScenePart scenePart)
        {
            this._ctlMainFrame.PreliminaryLoadPart(scenePart, UIContext.Current.IsShowActiveXPart);
        }

        /// <summary>
        /// 滚动场景
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="offset">本次增量</param>
        public void LoopScene(int direction, double offset)
        {
            if (direction == 0)
            {
                // left
                this._ctlMainFrame.HLoop(offset);
            }
            else if (direction == 2)
            {
                // right
                this._ctlMainFrame.HLoop(-offset);
            }

            // 设置视图状态
            ScenePart scenePart = this._ctlMainFrame.CurrentPart as ScenePart;
            this._viewState.SetPartProperty(scenePart.XFullName, ScenePart.VS_LOOPH, scenePart.DestHLoopOffset.ToString());
            this._viewState.Update();
        }

        public void LoopSceneTo(double destOffset)
        {
            this._ctlMainFrame.HLoopTo(destOffset);
        }

        //protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        //{
        //    Swap("S1A1","S1A3");
        //    base.OnPreviewMouseDown(e);
        //}

        /// <summary>
        /// 交换两个区域对象的位置
        /// </summary>
        /// <param name="sourceArea"></param>
        /// <param name="destArea"></param>
        private void Swap(string sourceArea, string destArea)
        {
            if (sourceArea == destArea)
            {
                return;
            }
            this._ctlMainFrame.SwapArea(sourceArea, destArea);
        }

        /// <summary>
        /// 交换区域
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="sourceArea"></param>
        /// <param name="destArea"></param>
        [Obsolete("目前启用场景中区域移动的方法，不用交换方法")]
        public void SwapArea(string scene, string sourceArea, string destArea)
        {
            Common.Logger.DebugToTag("UI", "RenderView OnReceiveSwapAreaCompletedEvent source:{0} dest:{1}",
                sourceArea,
                destArea);

            Swap(sourceArea, destArea);

            Common.EventBus.Instance.Publish(new Event.SwapAreaCompletedEvent(scene, sourceArea, destArea));
        }

        /// <summary>
        /// [API]
        /// 移动区域将sourcearea移动到destArea的前面
        /// 如果从左往右则移动到destArea的后面
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="sourceArea"></param>
        /// <param name="destArea"></param>
        public void MoveArea(string scene, string sourceArea, string destArea)
        {
            if (sourceArea == destArea)
            {
                return;
            }

            this.Dispatcher.Invoke(() =>
            {
                _ctlMainFrame.MoveArea(sourceArea, destArea);
                #region 设置视图状态
                ScenePart scenePart = this._ctlMainFrame.CurrentPart as ScenePart;
                StringBuilder areaposBuilder = new StringBuilder();
                for (int index = 0; index < scenePart.ChildrenPosInfo.Count; index++)
                {
                    ChildPos childPos = scenePart.ChildrenPosInfo[index];
                    areaposBuilder.AppendFormat("{0}:{1},", childPos.Name, childPos.Left);
                }
                this._viewState.SetPartProperty(scenePart.Name, ScenePart.VS_AREAPOS, areaposBuilder.ToString());
                this._viewState.Update();
                #endregion
            });
        }

        /// <summary>
        /// 切换tab组件的选项卡
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="tabContainer"></param>
        /// <param name="oldTabIndex"></param>
        /// <param name="newTabIndex"></param>
        public void TabChange(string scene, string tabContainer, int oldTabIndex, int newTabIndex)
        {
            Common.Logger.DebugToTag("UI", "RenderView OnReceiveTabChangeCompetedEvent OldTabIndex:{0} NewTabIndex:{1} Scene:{2} TabContainer:{3}  ",
              oldTabIndex,
              newTabIndex,
              scene,
              tabContainer);
            this.Dispatcher.Invoke(() =>
            {
                UI.TabContainerPart containerPart = (this._ctlMainFrame.CurrentPart as IPartContainer).GetChildPart(tabContainer, true) as UI.TabContainerPart;
                if (containerPart != null)
                {
                    containerPart.SelectTab(newTabIndex);

                    #region 设置视图状态
                    this._viewState.SetPartProperty(containerPart.Name, UI.TabContainerPart.VS_TAB, newTabIndex.ToString());
                    this._viewState.Update();
                    #endregion

                    Common.EventBus.Instance.Publish(new Event.TabChangeCompetedEvent(oldTabIndex,
                        newTabIndex,
                        scene,
                        tabContainer));
                }
                else
                {
                    Common.Logger.ErrorToTag("UI", "未获取到Tab组件：{0}", tabContainer);
                }
            });
        }

        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            ScenePart scene = this._ctlMainFrame.CurrentPart as ScenePart;
            if (scene != null)
            {
                Point point = e.GetPosition(scene);
                if (scene.HActualLoopOffset != 0)
                {
                    if (scene.HVirtualLoopOffset < scene.HActualLoopOffset && point.X < scene.HActualLoopOffset)
                    {
                        point.X = scene.HActualLoopOffset + (this.ActualWidth - (scene.HActualLoopOffset - point.X));
                    }
                    else if (scene.HVirtualLoopOffset > scene.HActualLoopOffset && point.X > scene.HVirtualLoopOffset)
                    {
                        point.X = scene.HActualLoopOffset + point.X;
                    }
                }

                UI.Part part = scene.GetPartAtPoint(typeof(Part), point, scene);
                if (part != null)
                {
                    Common.Logger.DebugToTag("UI", "Part:{0},MouseLeftButtonDown point:{1},{2}", part.Name, point.X, point.Y);
                    Service.Contract.ReqMouseEventData requestData = new Service.Contract.ReqMouseEventData();
                    requestData.SceneName = scene.Name;
                    requestData.PartName = part.Name;
                    requestData.EventSource = MouseEventType.MouseLeftDown.Name;
                    requestData.PointX = point.X;
                    requestData.PointY = point.Y;
                    ServiceProxy.ClientProxyManager.Instance.SendRequestSys(
                        UIContext.Current.ControlDomainId,
                        UIContext.Current.UserIdentity,
                        Service.Contract.REQUEST_SCENARIO.SCENE,
                        Service.Contract.REQUEST_COMMAND.SCENE.MOUSEEVENT,
                        Service.Contract.REQUEST_MODE.ALL,
                        requestData);
                    //part.RaiseMouseEvent(MouseEventType.MouseLeftDown, point);
                }
            }
            base.OnPreviewMouseLeftButtonDown(e);
        }

        [Subscribe]
        public void OnReceiveMouseEventData(Service.Contract.RespMouseEventData responseData)
        {
            this.Dispatcher.Invoke(() =>
            {
                ScenePart scene = this._ctlMainFrame.CurrentPart as ScenePart;
                if (scene != null && scene.Name == responseData.SceneName)
                {
                    UI.Part part = scene.GetChildPart(responseData.PartName, true);
                    if (part != null)
                    {
                        part.RaiseMouseEvent(MouseEventType.Get(responseData.EventSource), new Point(responseData.PointX, responseData.PointY));
                    }
                }
            });
        }

        /// <summary>
        /// 获取现在所显示的区域在场景中的区域信息
        /// </summary>
        /// <returns></returns>
        public Rect GetViewRegionInScene()
        {
            if (this._ctlMainFrame.CurrentPart != null)
            {
                //Point ptRenderView = this._ctlMainFrame.PointToScreen(new Point(0, 0));
                //Point ptScene = this._ctlMainFrame.CurrentPart.PointToScreen(new Point(0, 0));

                //double deltaX = ptRenderView.X - ptScene.X;
                //double deltaY = ptRenderView.Y - ptScene.Y;
                //return new Rect(deltaX, deltaY, this._ctlMainFrame.ActualWidth, this._ctlMainFrame.ActualHeight);
                return new Rect(this._ctlMainFrame.HorizontalOffset,
                    this._ctlMainFrame.VerticalOffset,
                    this._ctlMainFrame.ActualWidth,
                    this._ctlMainFrame.ActualHeight);
            }
            else
            {
                return Rect.Empty;
            }
        }

        void _ctlMainFrame_OnSceneUpdated(ScenePart scene)
        {
            Common.EventBus.Instance.Publish(new SceneUpdateEvent(scene, SceneUpdateReason.MoveCamera));
        }

        void _ctlMainFrame_OnSceneOpened(ScenePart scene)
        {
            OnUpdateScrollBar(this.RenderSize);
            Common.EventBus.Instance.Publish(new SceneUpdateEvent(scene, SceneUpdateReason.Open));
        }

        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="scriptCode"></param>
        public void ExecuteJs(string scriptCode)
        {
            _ctlMainFrame.ExecuteJs(scriptCode);
        }

        public void ValidateCurrentPartVisibleRange()
        {
            if (_popViews != null && _popViews.Count > 0)
            {
                (_popViews[_popViews.Count - 1].ContentView as RenderView).ValidateCurrentPartVisibleRange();
            }
            else
            {
                _ctlMainFrame.ValidateCurrentPartVisibleRange();
            }
        }

        /// <summary>
        /// 清楚渲染视图里所有的组件引用关系
        /// </summary>
        public void ClearAllParts()
        {
            if (_popViews != null && _popViews.Count > 0)
            {
                for (int index = 0; index < _popViews.Count; index++)
                {
                    (_popViews[index].ContentView as RenderView).ClearAllParts();
                }
            }

            // 保存状态的age不变
            long storeViewStateAge = _viewState.Age;
            _viewState = Coolzon.ViewState.ViewState.FromToken(string.Empty);
            _viewState.UpdateAge(storeViewStateAge++);

            _ctlMainFrame.ClearAllParts();

            this.Solution = null;
            this.CurrentScene = null;
        }

        public PartContext GetPartContext()
        {
            return _ctlMainFrame.PartContext;
        }

        #region magnify
        private VisualBrush _magnifierVisualBrush;
        private Storyboard _moveMagnifyStoryboard;
        private DoubleAnimation _moveMagnifyAnimationTop;
        private DoubleAnimation _moveMagnifyAnimationLeft;
        public void ShowMagnify(Point pos, double rate, double radius, double duration)
        {
            this.Dispatcher.Invoke(() =>
            {
                double sourceW = 800 / 2.0d;
                double sourceH = 800 / 2.0d;
                double halfW = 800 / 2.0d;
                double halfH = 800 / 2.0d;
                double left = pos.X - halfW;
                double top = pos.Y - halfH;

                double currentLeft = 0;
                double currentTop = 0;
                if (_magnifierVisualBrush == null)
                {
                    currentLeft = 0;
                    currentTop = 0;

                    _magnifierVisualBrush = new VisualBrush(this.GetCurrentPart());
                    _magnifierVisualBrush.ViewboxUnits = BrushMappingMode.Absolute;
                    _magnifierVisualBrush.Viewbox = new Rect(pos.X - sourceW / 2, pos.Y - sourceH / 2, sourceW, sourceH);
                    _ctlMagnifier.Fill = _magnifierVisualBrush;
                }
                else
                {
                    currentLeft = Canvas.GetLeft(this._ctlMagnifier);
                    currentTop = Canvas.GetTop(this._ctlMagnifier);
                    //_magnifierVisualBrush.Viewbox = new Rect(pos.X - sourceW / 2, pos.Y - sourceH / 2, sourceW, sourceH);
                }

                if (_moveMagnifyStoryboard == null)
                {
                    _moveMagnifyStoryboard = new Storyboard();
                    //_moveMagnifyStoryboard.FillBehavior = FillBehavior.HoldEnd;
                    _moveMagnifyAnimationTop = new DoubleAnimation(currentTop, top, new Duration(TimeSpan.FromSeconds(duration)));
                    Storyboard.SetTarget(_moveMagnifyAnimationTop, this);
                    Storyboard.SetTargetProperty(_moveMagnifyAnimationTop, new PropertyPath(RenderView.XMagnifyTopProperty));

                    _moveMagnifyAnimationLeft = new DoubleAnimation(currentLeft, left, new Duration(TimeSpan.FromSeconds(duration)));
                    Storyboard.SetTarget(_moveMagnifyAnimationLeft, this);
                    Storyboard.SetTargetProperty(_moveMagnifyAnimationLeft, new PropertyPath(RenderView.XMagnifyLeftProperty));

                    _moveMagnifyStoryboard.Children.Add(_moveMagnifyAnimationTop);
                    _moveMagnifyStoryboard.Children.Add(_moveMagnifyAnimationLeft);
                    _moveMagnifyStoryboard.Begin(_ctlMagnifier);
                }
                else
                {
                    _moveMagnifyAnimationTop.From = currentTop;
                    _moveMagnifyAnimationTop.To = top;

                    _moveMagnifyAnimationLeft.From = currentLeft;
                    _moveMagnifyAnimationLeft.To = left;
                    //_moveMagnifyStoryboard.Remove(this);
                    _moveMagnifyStoryboard.Begin(_ctlMagnifier);
                }

                this._ctlMagnifier.Visibility = Visibility.Visible;
            });
        }

        public void HideMagnify()
        {
            this.Dispatcher.Invoke(() =>
            {
                //_ctlMainFrame.HideMagnify();

                _ctlMagnifier.Fill = null;
                _magnifierVisualBrush = null;
                this._ctlMagnifier.Visibility = Visibility.Hidden;
            });
        }
        #endregion

        #region laser pointer
        public void ShowLaserPointer(Point pos, double radius, double duration, int color)
        {
            //this.Dispatcher.Invoke(() =>
            //{
            //    _ctlMainFrame.ShowLaserPointer(pos, radius, duration, color);
            //});
        }

        public void HideLaserPointer()
        {
            this.Dispatcher.Invoke(() =>
            {
                _ctlMainFrame.HideLaserPointer();
            });
        }
        #endregion

        /// <summary>
        /// 重置方案
        /// </summary>
        public void ResetSolution()
        {
            _viewState.UpdateAndResetPartState();
            // 重置当前方案
            // 默认显示到第一个场景上
            UI.Data.OpenSceneArgs openSceneArgs = new UI.Data.OpenSceneArgs();
            openSceneArgs.ParametersString.Add("sys:isresetviewstate", "true");
            OpenScene(SwitchMode.Replace, "", "", Solution.Scenes.First().Name, openSceneArgs);
        }

        /// <summary>
        /// 重置场景
        /// </summary>
        /// <param name="scene"></param>
        public void ResetScene(ScenePart scene)
        {
            ScenePart currentScene = _ctlMainFrame.CurrentPart as ScenePart;
            if (currentScene != null)
            {
                // 重置场景里的显示效果
                currentScene.Reset();
                currentScene.ResetViewState(_viewState);
                _viewState.Update();
            }
        }

        #region viewstate

        /// <summary>
        /// 更新组件的视图状态
        /// 当组件的收到事件后更新了自己的显示，需要保存视图状态
        /// </summary>
        /// <param name="part"></param>
        public void UpdatePartViewState(UI.Part part)
        {
            this.Dispatcher.Invoke(() =>
            {
                part.SaveViewState(_viewState);
            });
            _viewState.Update();
        }

        /// <summary>
        /// 重置视图状态，但是不更新组件的渲染效果
        /// </summary>
        public void ResetViewStateNotUpdatePart()
        {
            long storeViewStateAge = _viewState.Age;
            _viewState = Coolzon.ViewState.ViewState.FromToken(string.Empty);
            _viewState.UpdateAge(storeViewStateAge++);
        }

        public void SetViewState(Coolzon.ViewState.ViewState viewState)
        {
            this.Dispatcher.Invoke(() =>
            {
                _viewState = viewState;
                _ctlMainFrame.SetViewState(viewState);
            });
        }

        public string GetViewStateToken()
        {
            return Coolzon.ViewState.ViewState.ToToken(this._viewState);
        }

        public Coolzon.ViewState.ViewState GetViewState()
        {
            return this._viewState;
        }
        #endregion

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            OnUpdateScrollBar(sizeInfo.NewSize);
            base.OnRenderSizeChanged(sizeInfo);
        }
    }
}
